package com.cloud.cmt.usermanage.service.impl;

import com.angela.cloud.common.base.ResultMessage;
import com.cloud.cmt.usermanage.constant.EnterpriseConstants;
import com.cloud.cmt.usermanage.dao.EnterpriseUserDAO;
import com.cloud.cmt.usermanage.dao.repository.EnterpriseUserRepository;
import com.cloud.cmt.usermanage.entity.vo.AuditDetailVO;
import com.cloud.cmt.usermanage.entity.vo.AuditManagementVO;
import com.cloud.cmt.usermanage.service.AccountStatusChangeEvent;
import com.cloud.cmt.usermanage.service.UserManagementService;
import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.List;

/**
 * ,,
 * 浙江卓锐科技股份有限公司 版权所有 © Copyright 2017<br>
 * 说明: <br>
 * 项目名称: cloud-maintenance <br>
 * 创建日期: 2017年10月29日 16:08 <br>
 * 作者: <a href="6492178@gmail.com">汪萌萌</a>
 */
@Service
public class UserManagementServiceImpl implements UserManagementService {
    private static Logger LOGGER = LoggerFactory.getLogger(UserManagementServiceImpl.class);
    @Resource
    private EntityManager entityManager;
    @Resource
    private EnterpriseUserRepository userRepository;
    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public ResultMessage<List<AuditManagementVO>> getAuditManagementsByAccountStatus(Pageable pageable, int[] accountStatus, String conditions) {
        //<editor-fold desc="sq l示例">
        /*select
        enterprise0_.id as col_0_0_,
                enterprise0_.user_code as col_1_0_,
        enterprise0_.organization_name as col_2_0_,
        case enterprise0_.industry when 1 then '酒店' when 2 then '物业' else '无' end as col_3_0_,
        case when employee3_.name is null then '无' else employee3_.name end as col_4_0_,
        enterprise1_.apply_for_time as col_5_0_
                from
        enterprise_detail enterprise0_
        left outer join enterprise_user enterprise1_ on (enterprise0_.id = enterprise1_.enterprise_id)
        left outer join enterprise_referrer enterprise2_ on (
                enterprise1_.enterprise_id = enterprise2_.enterprise_id
        )
        left outer join employee employee3_ on (enterprise2_.referrer = employee3_.employee_num)
        where
        enterprise1_.account_status = 1
        order by
        enterprise1_.apply_for_time desc
        limit
        10*/
        //</editor-fold>

        StringBuilder hql = new StringBuilder("select new com.cloud.cmt.usermanage.entity.vo.AuditManagementVO(d.id,d.userCode,d.organizationName, ");
        hql.append(" d.industry,e.name, u.applyForTime,u.accountStatus,u.enable)")
                .append(" from enterpriseDetail d left join enterpriseUser u on d.id=u.enterpriseId ")
                .append(" left join enterpriseReferrer r on u.enterpriseId=r.enterpriseId")
                .append(" left join Employee e on r.referrer=e.employeeNum")
                .append(" where u.accountStatus in (");
        String str = "";
        for (int i = 0; i < accountStatus.length; i++) {
            str += accountStatus[i];
            if (i != accountStatus.length - 1) {
                str += ",";
            }
        }
        hql.append(str).append(") ");
        if (!Strings.isNullOrEmpty(conditions)) {
            hql.append(" and (d.organizationName like ('%").append(conditions).append("%') ")
                    .append(" or e.name like ('%").append(conditions).append("%'))");
        }
        hql.append(" order by u.applyForTime desc");
        TypedQuery<AuditManagementVO> query = entityManager.createQuery(hql.toString(), AuditManagementVO.class);
        int totalRows = query.getResultList().size();
        List<AuditManagementVO> resultList = query
                .setFirstResult(pageable.getPageNumber() * pageable.getPageSize())
                .setMaxResults(pageable.getPageSize())
                .getResultList();
        return ResultMessage.success(new PageImpl(resultList, pageable, totalRows));

    }

    @Override
    public ResultMessage getEnterpriseDetailById(Long id) {
        StringBuilder hql = new StringBuilder("select new com.cloud.cmt.usermanage.entity.vo.AuditDetailVO(d,u,e.name ) from ")
                .append(" enterpriseDetail d left join enterpriseUser u on d.id=u.enterpriseId ")
                .append(" left join enterpriseReferrer r on u.enterpriseId=r.enterpriseId ")
                .append(" left join Employee e on r.referrer=e.employeeNum ")
                .append(" where d.id=").append(id);
        TypedQuery<AuditDetailVO> query = entityManager.createQuery(hql.toString(), AuditDetailVO.class);
        if (CollectionUtils.isEmpty(query.getResultList())) {
            return ResultMessage.defaultError("该id不存在");
        }
        return ResultMessage.success(query.getSingleResult());
    }

    @Override
    public ResultMessage auditPassById(Long id) {
        ResultMessage<EnterpriseUserDAO> resultMessage = this.checkAccountStatusIsAllowToChange(id, EnterpriseConstants.ACCOUNT_STATUS_PROBATIONING);
        if (!resultMessage.getIsSuccess()) {
            return resultMessage;
        }
        EnterpriseUserDAO enterpriseUserDAO = resultMessage.getData();
        userRepository.save(enterpriseUserDAO);
        //TODO 设置试用套餐
        //TODO 保存日志
        //TODO 发送审核通过短信
        //TODO 运营数据插入
        return ResultMessage.success("操作成功");
    }

    @Override
    public ResultMessage auditNotPassById(Long id) {
        ResultMessage<EnterpriseUserDAO> resultMessage = this.checkAccountStatusIsAllowToChange(id, EnterpriseConstants.ACCOUNT_STATUS_NO_AUDIT);
        if (!resultMessage.getIsSuccess()) {
            return resultMessage;
        }
        EnterpriseUserDAO enterpriseUserDAO = resultMessage.getData();
        userRepository.save(enterpriseUserDAO);
        //TODO 保存日志
        //TODO 发送审核未通过短信
        //TODO 运营数据插入

        return ResultMessage.success("操作成功");
    }

    @Override
    public ResultMessage addBlackListById(Long id) {
        ResultMessage<EnterpriseUserDAO> resultMessage = this.checkAccountStatusIsAllowToChange(id, EnterpriseConstants.ACCOUNT_STATUS_DISABLE);
        if (!resultMessage.getIsSuccess()) {
            return resultMessage;
        }
        EnterpriseUserDAO enterpriseUserDAO = resultMessage.getData();
        userRepository.save(enterpriseUserDAO);
        //TODO 保存日志
        //TODO 发送账号禁用短信
        return ResultMessage.success("操作成功");
    }

    @Override
    public ResultMessage removeBlackListById(Long id) {
        ResultMessage<EnterpriseUserDAO> resultMessage = this.checkAccountStatusIsAllowToChange(id, EnterpriseConstants.ACCOUNT_STATUS_ENABLE);
        if (!resultMessage.getIsSuccess()) {
            return resultMessage;
        }
        EnterpriseUserDAO enterpriseUserDAO = resultMessage.getData();
        userRepository.save(enterpriseUserDAO);
        //TODO 保存日志
        //TODO 发送账号解禁短信
        return ResultMessage.success("操作成功");
    }

    @Override
    public ResultMessage<EnterpriseUserDAO> checkAccountStatusIsAllowToChange(Long enterpriseId, EnterpriseConstants statusToChange) {
        EnterpriseUserDAO userDAO = userRepository.getFirstByEnterpriseId(enterpriseId);
        if (userDAO == null) {
            return ResultMessage.defaultError("企业不存在");
        }
        int accountStatus = userDAO.getAccountStatus();
        AccountStatusChangeEvent accountStatusChangeEvent = new AccountStatusChangeEvent();
        ResultMessage success = ResultMessage.success(userDAO);
        ResultMessage error = ResultMessage.defaultError("该账户状态不允许进行变更操作,请检查后重试,或联系系统管理员");
        switch (statusToChange) {
            //只有待审核状态可以变成审核不通过
            case ACCOUNT_STATUS_NO_AUDIT:
                if (accountStatus == EnterpriseConstants.ACCOUNT_STATUS_PENDING_AUDIT.getValue()) {
                    userDAO.setAccountStatus(statusToChange.getValue());
                    accountStatusChangeEvent.setUserDAO(userDAO);
                    applicationEventPublisher.publishEvent(accountStatusChangeEvent);
                    return success;
                }
                return error;

            //只有审核不通过的账号可以变成待审核状态
            case ACCOUNT_STATUS_PENDING_AUDIT:
                if (accountStatus == EnterpriseConstants.ACCOUNT_STATUS_NO_AUDIT.getValue()) {
                    userDAO.setAccountStatus(statusToChange.getValue());
                    accountStatusChangeEvent.setUserDAO(userDAO);
                    applicationEventPublisher.publishEvent(accountStatusChangeEvent);
                    return success;
                }
                return error;

            //只有待审核或审核不通过的账号可以变成试用中的状态
            case ACCOUNT_STATUS_PROBATIONING:
                if (accountStatus == EnterpriseConstants.ACCOUNT_STATUS_PENDING_AUDIT.getValue() || accountStatus == EnterpriseConstants.ACCOUNT_STATUS_NO_AUDIT.getValue()) {
                    userDAO.setAccountStatus(statusToChange.getValue());
                    accountStatusChangeEvent.setUserDAO(userDAO);
                    applicationEventPublisher.publishEvent(accountStatusChangeEvent);
                    return success;
                }
                return error;
            //只有试用中或已流失的账号可以变成使用中的状态
            case ACCOUNT_STATUS_PAIED:
                if (accountStatus == EnterpriseConstants.ACCOUNT_STATUS_PROBATIONING.getValue() || accountStatus == EnterpriseConstants.ACCOUNT_STATUS_DRAIN_AWAY.getValue()) {
                    userDAO.setAccountStatus(statusToChange.getValue());
                    accountStatusChangeEvent.setUserDAO(userDAO);
                    applicationEventPublisher.publishEvent(accountStatusChangeEvent);
                    return success;
                }
                return error;

            //只有试用中或使用中的的账号可以变成已流失的状态
            case ACCOUNT_STATUS_DRAIN_AWAY:
                if (accountStatus == EnterpriseConstants.ACCOUNT_STATUS_PENDING_AUDIT.getValue() || accountStatus == EnterpriseConstants.ACCOUNT_STATUS_PAIED.getValue()) {
                    userDAO.setAccountStatus(statusToChange.getValue());
                    accountStatusChangeEvent.setUserDAO(userDAO);
                    applicationEventPublisher.publishEvent(accountStatusChangeEvent);
                    return success;
                }
                return error;

            case ACCOUNT_STATUS_DISABLE:
                userDAO.setEnable(false);
                accountStatusChangeEvent.setEnableFlag(true);
                accountStatusChangeEvent.setUserDAO(userDAO);
                applicationEventPublisher.publishEvent(accountStatusChangeEvent);
                return success;
            case ACCOUNT_STATUS_ENABLE:
                userDAO.setEnable(true);
                accountStatusChangeEvent.setEnableFlag(true);
                accountStatusChangeEvent.setUserDAO(userDAO);
                applicationEventPublisher.publishEvent(accountStatusChangeEvent);
                return success;
            default:
                return error;
        }


    }

}
